using AuthService.Infrastructure.Monitoring;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using System.Text.Json;

namespace AuthService.Api.Controllers;

/// <summary>
/// 健康检查和监控控制器
/// 提供健康状态和系统指标查询接口
/// </summary>
[ApiController]
[Route("api/[controller]")]

public class HealthController : ControllerBase
{
    private readonly HealthCheckService _healthCheckService;
    private readonly IMetricsCollector _metricsCollector;
    private readonly ILogger<HealthController> _logger;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="healthCheckService">健康检查服务</param>
    /// <param name="metricsCollector">指标收集器</param>
    /// <param name="logger">日志记录器</param>
    public HealthController(
        HealthCheckService healthCheckService,
        IMetricsCollector metricsCollector,
        ILogger<HealthController> logger)
    {
        _healthCheckService = healthCheckService;
        _metricsCollector = metricsCollector;
        _logger = logger;
    }

    /// <summary>
    /// 获取基础健康状态
    /// </summary>
    /// <returns>返回系统的基础健康状态信息，包含服务状态和基本指标</returns>
    /// <response code="200">系统健康</response>
    /// <response code="503">系统不健康</response>
    /// <example>
    /// GET /api/health
    /// </example>
    [HttpGet]
    [AllowAnonymous]
    [ProducesResponseType(typeof(object), 200)]
    [ProducesResponseType(503)]
    public async Task<IActionResult> GetHealth()
    {
        try
        {
            var healthReport = await _healthCheckService.CheckHealthAsync();

            var response = new
            {
                status = healthReport.Status.ToString(),
                totalDuration = healthReport.TotalDuration.TotalMilliseconds,
                entries = healthReport.Entries.Select(entry => new
                {
                    name = entry.Key,
                    status = entry.Value.Status.ToString(),
                    duration = entry.Value.Duration.TotalMilliseconds,
                    description = entry.Value.Description,
                    data = entry.Value.Data,
                    exception = entry.Value.Exception?.Message,
                    tags = entry.Value.Tags
                })
            };

            var statusCode = healthReport.Status switch
            {
                HealthStatus.Healthy => 200,
                HealthStatus.Degraded => 200,
                HealthStatus.Unhealthy => 503,
                _ => 500
            };

            return StatusCode(statusCode, response);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取健康状态失败");
            return StatusCode(500, new { status = "Unhealthy", error = ex.Message });
        }
    }

    /// <summary>
    /// 获取详细健康状态
    /// </summary>
    /// <returns>详细健康状态</returns>
    [HttpGet("detailed")]
    [Authorize(Policy = "AdminOnly")]
    public async Task<IActionResult> GetDetailedHealth()
    {
        try
        {
            var healthReport = await _healthCheckService.CheckHealthAsync();

            var response = new
            {
                status = healthReport.Status.ToString(),
                totalDuration = healthReport.TotalDuration.TotalMilliseconds,
                checkedAt = DateTime.UtcNow,
                entries = healthReport.Entries.Select(entry => new
                {
                    name = entry.Key,
                    status = entry.Value.Status.ToString(),
                    duration = entry.Value.Duration.TotalMilliseconds,
                    description = entry.Value.Description,
                    data = entry.Value.Data,
                    exception = entry.Value.Exception?.ToString(), // 包含完整异常信息
                    tags = entry.Value.Tags
                }),
                systemInfo = new
                {
                    machineName = Environment.MachineName,
                    osVersion = Environment.OSVersion.ToString(),
                    processorCount = Environment.ProcessorCount,
                    workingSet = Environment.WorkingSet,
                    version = Environment.Version.ToString(),
                    is64BitProcess = Environment.Is64BitProcess,
                    is64BitOperatingSystem = Environment.Is64BitOperatingSystem
                }
            };

            var statusCode = healthReport.Status switch
            {
                HealthStatus.Healthy => 200,
                HealthStatus.Degraded => 200,
                HealthStatus.Unhealthy => 503,
                _ => 500
            };

            return StatusCode(statusCode, response);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取详细健康状态失败");
            return StatusCode(500, new { status = "Unhealthy", error = ex.Message });
        }
    }

    /// <summary>
    /// 获取特定标签的健康检查
    /// </summary>
    /// <param name="tags">标签列表</param>
    /// <returns>健康状态</returns>
    [HttpGet("tags")]
    [AllowAnonymous]
    public async Task<IActionResult> GetHealthByTags([FromQuery] string[] tags)
    {
        try
        {
            var healthReport = await _healthCheckService.CheckHealthAsync(check =>
                tags.Any(tag => check.Tags.Contains(tag)));

            var response = new
            {
                status = healthReport.Status.ToString(),
                totalDuration = healthReport.TotalDuration.TotalMilliseconds,
                requestedTags = tags,
                entries = healthReport.Entries.Select(entry => new
                {
                    name = entry.Key,
                    status = entry.Value.Status.ToString(),
                    duration = entry.Value.Duration.TotalMilliseconds,
                    description = entry.Value.Description,
                    tags = entry.Value.Tags
                })
            };

            var statusCode = healthReport.Status switch
            {
                HealthStatus.Healthy => 200,
                HealthStatus.Degraded => 200,
                HealthStatus.Unhealthy => 503,
                _ => 500
            };

            return StatusCode(statusCode, response);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取标签健康状态失败");
            return StatusCode(500, new { status = "Unhealthy", error = ex.Message });
        }
    }

    /// <summary>
    /// 获取系统指标
    /// </summary>
    /// <returns>系统指标</returns>
    [HttpGet("metrics")]
    [Authorize(Policy = "AdminOnly")]
    public IActionResult GetMetrics()
    {
        try
        {
            var metrics = _metricsCollector.GetMetricsSummary();
            return Ok(metrics);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取系统指标失败");
            return StatusCode(500, new { error = ex.Message });
        }
    }

    /// <summary>
    /// 获取API请求指标
    /// </summary>
    /// <returns>API请求指标</returns>
    [HttpGet("metrics/api")]
    [Authorize(Policy = "AdminOnly")]
    public IActionResult GetApiMetrics()
    {
        try
        {
            var metrics = _metricsCollector.GetMetricsSummary();
            return Ok(metrics.ApiRequests);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取API指标失败");
            return StatusCode(500, new { error = ex.Message });
        }
    }

    /// <summary>
    /// 获取数据库指标
    /// </summary>
    /// <returns>数据库指标</returns>
    [HttpGet("metrics/database")]
    [Authorize(Policy = "AdminOnly")]
    public IActionResult GetDatabaseMetrics()
    {
        try
        {
            var metrics = _metricsCollector.GetMetricsSummary();
            return Ok(metrics.Database);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取数据库指标失败");
            return StatusCode(500, new { error = ex.Message });
        }
    }

    /// <summary>
    /// 获取系统资源指标
    /// </summary>
    /// <returns>系统资源指标</returns>
    [HttpGet("metrics/system")]
    [Authorize(Policy = "AdminOnly")]
    public IActionResult GetSystemMetrics()
    {
        try
        {
            var metrics = _metricsCollector.GetMetricsSummary();
            return Ok(metrics.System);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取系统资源指标失败");
            return StatusCode(500, new { error = ex.Message });
        }
    }

    /// <summary>
    /// 获取就绪状态（用于Kubernetes就绪探针）
    /// </summary>
    /// <returns>就绪状态</returns>
    [HttpGet("ready")]
    [AllowAnonymous]
    public async Task<IActionResult> GetReadiness()
    {
        try
        {
            // 检查关键服务是否就绪
            var healthReport = await _healthCheckService.CheckHealthAsync(check =>
                check.Tags.Contains("database") || check.Tags.Contains("consul"));

            if (healthReport.Status == HealthStatus.Healthy)
            {
                return Ok(new { status = "Ready", timestamp = DateTime.UtcNow });
            }
            else
            {
                return StatusCode(503, new { status = "NotReady", timestamp = DateTime.UtcNow });
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取就绪状态失败");
            return StatusCode(503, new { status = "NotReady", error = ex.Message, timestamp = DateTime.UtcNow });
        }
    }

    /// <summary>
    /// 获取存活状态（用于Kubernetes存活探针）
    /// </summary>
    /// <returns>存活状态</returns>
    [HttpGet("live")]
    [AllowAnonymous]
    public IActionResult GetLiveness()
    {
        try
        {
            // 简单的存活检查
            return Ok(new { status = "Alive", timestamp = DateTime.UtcNow });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取存活状态失败");
            return StatusCode(500, new { status = "Dead", error = ex.Message, timestamp = DateTime.UtcNow });
        }
    }
}
